﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Pg.BioMedics.SDR.Web.Controls
{
    // TODO: More detailed description
    /// <summary>
    /// ActionToolbar web control. this contrl acts as an action navigator. 
    /// 
    /// </summary>
    [ToolboxData("<{0}:ActionToolbar runat=\"server\"></{0}:ActionToolbar>")]
    [ToolboxItem(true)]
    [PersistChildren(true)]
    public class ActionToolbar : WebControl, INamingContainer
    {
        #region Constants

        private const string CommandParametersSeparator = "<#?#>";

        #endregion

        #region Fields

        private List<ActionGroup> groups = new List<ActionGroup>();
        private Dictionary<string, LinkButton> actionControls = new Dictionary<string, LinkButton>();

        private string groupHeaderCssClass;
        private string groupCssClass;
        private string actionCssClass;
        private string actionHolderCssClass;
        private string actionSelectedCssClass;

        #endregion

        #region Properties

        /// <summary>
        /// Gets collection of action groups
        /// </summary>
        public List<ActionGroup> Groups
        {
            get
            {
                return this.groups;
            }
        }

        /// <summary>
        /// Gets / sets action group css class
        /// </summary>
        public string GroupCssClass
        {
            get
            {
                return this.groupCssClass;
            }

            set
            {
                this.groupCssClass = value;
            }
        }

        /// <summary>
        /// Gets / sets group header css class
        /// </summary>
        public string GroupHeaderCssClass
        {
            get
            {
                return this.groupHeaderCssClass;
            }

            set
            {
                this.groupHeaderCssClass = value;
            }
        }

        /// <summary>
        /// Gets / sets action button css class
        /// </summary>
        public string ActionCssClass
        {
            get
            {
                return this.actionCssClass;
            }

            set
            {
                this.actionCssClass = value;
            }
        }

        /// <summary>
        /// Gets / sets action holder css class
        /// </summary>
        public string ActionHolderCssClass
        {
            get
            {
                return this.actionHolderCssClass;
            }

            set
            {
                this.actionHolderCssClass = value;
            }
        }

        /// <summary>
        /// Gets / sets action selected Css class
        /// </summary>
        public string ActionSelectedCssClass
        {
            get
            {
                return this.actionSelectedCssClass;
            }

            set
            {
                this.actionSelectedCssClass = value;
            }
        }

        /// <summary>
        /// Gets / sets active view name. This property sets also 
        /// selected Css style class to action related with the view
        /// </summary>
        internal string ActiveViewName
        {
            set
            {
                RestoreAllActionsStyles();
                SetActiveActionStyle(value);
            }
        }

        #endregion

        #region Overriden methods

        protected override void CreateChildControls()
        {
            InitializeControls();
        }

        #endregion

        #region Event handlers

        private void actionButton_Click(object sender, EventArgs e)
        {
            LinkButton actionButton = sender as LinkButton;
            if (actionButton != null)
            {
                string[] arguments = actionButton.CommandArgument.Split(new string[]{ CommandParametersSeparator }, StringSplitOptions.None);
                string viewName = arguments[0];
                string parameter = arguments[1];                

                if (ActionInvoked != null)
                    ActionInvoked.Invoke(this, new ActionInvokedEventArgs() { ViewName = viewName, 
                                                                              Parameter = parameter });
            }
        }

        #endregion

        #region Support methods

        private void InitializeControls()
        {
            UpdatePanel updatePanel = new UpdatePanel();
            Controls.Add(updatePanel); 

            foreach (ActionGroup group in this.groups)
            {
                // prepare header for group
                Panel groupPanel = new Panel();
                groupPanel.CssClass = this.groupCssClass;

                updatePanel.ContentTemplateContainer.Controls.Add(groupPanel);
                updatePanel.ContentTemplateContainer.Controls.Add(new Literal() { Text = "<br />" });

                Panel groupPanelHeader = new Panel();
                groupPanelHeader.CssClass = this.groupHeaderCssClass;
                Label headerLabel = new Label();
                headerLabel.Text = group.Title;

                groupPanelHeader.Controls.Add(headerLabel);
                groupPanel.Controls.Add(groupPanelHeader);
                groupPanel.Controls.Add(new Literal() { Text = "<br />" });                

                foreach (Action action in group.Actions)
                {
                    // create link button holder
                    Panel actionHolderPanel = new Panel();
                    actionHolderPanel.CssClass = this.actionHolderCssClass;

                    groupPanel.Controls.Add(actionHolderPanel);
                    //groupPanel.Controls.Add(new Literal() { Text = "<br />" });

                    // create link button foreach group
                    LinkButton actionButton = new LinkButton();
                    actionButton.CausesValidation = false;
                    actionButton.Text = action.Title;
                    actionButton.CommandArgument = String.Format("{0}{1}{2}", action.ViewName, 
                                                                              CommandParametersSeparator, 
                                                                              action.Parameter);
                    actionButton.CssClass = this.actionCssClass;
                    actionButton.Click += new EventHandler(actionButton_Click);

                    actionHolderPanel.Controls.Add(actionButton);
                    actionControls.Add(action.ViewName, actionButton);
                }

                groupPanel.Controls.Add(new Literal() { Text = "<br />" });
            }
        }

        private void RestoreAllActionsStyles()
        {
            foreach (LinkButton actionButton in this.actionControls.Values)
                actionButton.CssClass = this.actionCssClass;
        }

        private void SetActiveActionStyle(string viewName)
        {
            if (this.actionControls.ContainsKey(viewName))
            {
                LinkButton actionButton = this.actionControls[viewName];
                actionButton.CssClass = this.actionSelectedCssClass;
            }
        }
        
        #endregion

        #region Events

        internal event ActionInvokedEventHandler ActionInvoked;

        #endregion
    }
}
